package sparrowGui.utils
{
	import flash.utils.Dictionary;

	/**
	 * 类Class和对象new出映射缓存,多用于列表组件等
	 * @author Pelephone
	 */
	public class ClassLinkCache
	{
		/**
		 * 不缓存项
		 */
		public static const NO_ITEM_CACHE:int = -1;
		/**
		 * 自动缓存项(数据最大长度缓存项)
		 */
		public static const AUTO_ITEM_CACHE:int = 0;
		
		/**
		 * 缓存的哈希对象主键是class转字符串<String,<Array>>
		 */
		private var cacheHash:Dictionary;
		/**
		 * 对象链表.双链表形式管理LRU缓存对象
		 */
		private var cacheLink:Array;
		
		private var _cacheSize:int;
		/**
		 * 类和类new出的对象缓存
		 * 通过此缓存可以控制Class,new了来的对象数量,不过麻烦的是需要put和get
		 */
		public function ClassLinkCache(capacity:int=100)
		{
			cacheHash = new Dictionary(true);
			cacheLink = [];
			cacheSize = capacity;
		}
		
		/**
		 * 将类new出来的对象放入缓存	
		 * @param obj
		 */
		public function putToLink(obj:Object):void
		{
			if(obj is Class) 
				throw new Error("只能放入class创建出来的对象,不能放入class");
			
			var clsName:String = changeClassName(obj);
			var arr:Array = cacheHash[clsName];
			if(!arr) arr = cacheHash[clsName] = [];
			
			arr.push(obj);
			cacheLink.push(obj);
//			// 超出就不缓存了
//			if(arr.length<cacheSize)
//				arr.push(obj);
		}
		
		/**
		 * 超出缓存的数量就开始移出
		 */
		private function lruRemoveCache():void
		{
			while(cacheLink.length>cacheSize)
			{
				var resObj:Object = cacheLink.shift();
				var clsName:String = changeClassName(resObj);
				var arr:Array = cacheHash[clsName];
				arr.splice(arr.indexOf(resObj), 1)[0];
				if(arr.length==0)
					delete cacheHash[clsName];
			}
		}
		
		/**
		 * 通过对象或者Class获取类名
		 * @param obj
		 */
		private function changeClassName(obj:Object):String
		{
			return obj.toString().substring((obj.toString()).indexOf(" ")+1);
		}
		
		/**
		 * 通过Class+缓存new出对象
		 * @param cla
		 * @return 
		 */
		public function getObjByClass(cla:Class):*
		{
			var clsName:String = changeClassName(cla);
			var arr:Array = cacheHash[clsName];
			if(arr && arr.length>0){
				var resObj:Object = arr.shift();
				cacheLink.splice(cacheLink.indexOf(resObj), 1)[0];
				if(arr.length==0)
					delete cacheHash[clsName];
				return resObj;
			}
			return null;
		}
		
		/**
		 * 清除所有缓存
		 */
		public function clearAll():void
		{
			cacheHash = new Dictionary(true);
			cacheLink = [];
		}

		/**
		 * 缓存的数量
		 */
		public function get cacheSize():int
		{
			return _cacheSize;
		}

		/**
		 * @private
		 */
		public function set cacheSize(value:int):void
		{
			_cacheSize = value;
			lruRemoveCache();
		}

	}
}